<?php

namespace C\S\GroupBuying;

use C\L\Service;
use C\M\GroupBuyingOrder;
use C\M\GroupBuyingUserOrder;
use C\M\UserAddress;
use C\M\Shipment;

class UserOrder extends Service
{
    protected function setModel()
    {
        $this->model = new \C\M\GroupBuyingUserOrder();
    }

    public function confirm($userId, $orderId, $quantity, $addressId)
    {
        // 获取团购订单
        $conditions = '1 = 1' .
            ' AND id = :id:' .
            ' AND state = :state:';
        $bind = [
            'id'    => $orderId,
            'state' => 'processing',
        ];

        $order = GroupBuyingOrder::findFirst(compact('conditions', 'bind'));
        if (!$order) {
            throw new \Exception('未找到符合条件的订单');
        }

        // 检查剩余数量
        $sum = GroupBuyingUserOrder::sum([
            'group_buying_order_id = ' . $order->id,
            'column' => 'quantity',
        ]);

        $orderOtherInfo = json_decode($order->other_info, true);

        $max = $orderOtherInfo['group_buying']['quantity_max'] - $order->quantity;

        if ($sum + $quantity > $max) {
            throw new \Exception('超过最大成团数');
        }

        // 获取地址
        $address = UserAddress::findFirst([
            'id = :id:',
            'bind' => ['id' => $addressId],
        ]);
        if (!$address) {
            throw new \Exception('未找到收货地址');
        }

        $userOrder = new GroupBuyingUserOrder;
        $userOrder->user_id               = $userId;
        $userOrder->group_buying_order_id = $orderId;
        $userOrder->address_id            = $addressId;
        $userOrder->quantity              = $quantity;
        $userOrder->state                 = 'paid';
        $userOrder->other_info            = null;

        $result = $userOrder->save();
        if (!$result) {
            throw new \Exception('下单失败');
        }
    }

    public function isOwner($id, $userId)
    {
        return (bool) GroupBuyingUserOrder::findFirst([
            'id = :id: AND user_id = :user_id:',
            'bind' => ['id' => $id, 'user_id' => $userId],
        ]);
    }

    public function shipment($id)
    {
        $conditions = 'shipable_id = :shipable_id: AND shipable_type = :shipable_type:';

        $bind = [
            'shipable_id'   => $id,
            'shipable_type' => 'group_buying_user_order',
        ];

        $shipment = Shipment::findFirst(compact('conditions', 'bind'));

        return $shipment;
    }

    public function cancel($id)
    {
        $userOrder = GroupBuyingUserOrder::findById($id);
        if (!$userOrder) {
            throw new \Exception('未找到对应订单');
        }

        if ($userOrder->state != 'checkout') {
            throw new \Exception('该订单状态下不可执行此操作');
        }

        $userOrder->state = 'cancelled';

        return $userOrder->save();
    }

    public function refund($id)
    {
        $userOrder = GroupBuyingUserOrder::findById($id);
        if (!$userOrder) {
            throw new \Exception('未找到对应订单');
        }

        switch ($userOrder->state) {
            case 'paid':
            case 'shipped':
            case 'delivered':
                break;
            default:
                throw new \Exception('该订单状态下不可执行此操作');
        }

        try {
            $this->di['db']->begin();

            $userOrder->state = 'refunded';

            $result = $userOrder->save();
            if (!$result) {
                throw new \Exception('退款失败');
            }

            $refundResult = $this->di['s_funds']->add(
                $userOrder->user_id,
                $userOrder->payment_amount,
                'money',
                'refund_user_order',
                '拼团订单退款',
                $userOrder->id
            );
            if (!$refundResult) {
                throw new \Exception('退款失败');
            }

            $this->di['db']->commit();
        } catch (\Exception $error) {
            if ($this->di['db']->isUnderTransaction()) {
                $this->di['db']->rollback();
            }
            throw $error;
        }

        return true;
    }
}
